using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BuildWheel;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using MouseButton = UnityEngine.UIElements.MouseButton;
using TreeView = UnityEngine.UIElements.TreeView;

public class HierarchyTree : SingletonBehaviour<HierarchyTree>
{
    private UIDocument uiroot;
    private TreeView treeView;

    public class HierarchyData
    {
        public int id;
        public int index;
        public Transform tf;
    }

    void Awake()
    {
        uiroot = GetComponent<UIDocument>();
        treeView = uiroot.rootVisualElement.Q<TreeView>("hierarchyTreeView");

        treeView.RegisterCallback<MouseDownEvent>(OnMouseClick);
        treeView.itemsChosen += (selectedItems) => { Debug.Log("Items chosen: " + string.Join(", ", selectedItems)); };
        treeView.selectedIndicesChanged += OnSelectChanged;
        treeView.destroyItem = element =>
        {
            // Debug.Log($"del:{element}");
        };
    }

    private void OnSelectChanged(IEnumerable<int> obj)
    {
        var temp = treeView.GetItemDataForIndex<HierarchyData>(treeView.selectedIndex);
        if (temp != null)
        {
            selectGameObject = temp.tf.gameObject;
            Inspector.Instance.Ref(selectGameObject);
        }
    }

    void OnMouseClick(MouseDownEvent evt)
    {
        if (evt.button == (int)MouseButton.RightMouse)
        {
            var item = treeView.selectedItem as HierarchyData;
            // Debug.Log($"右键点击节点: {item.tf}");
            List<MenuPopupData> ls = new List<MenuPopupData>();
            ls.Add(new MenuPopupData()
            {
                label = "del",
                onback = OnDel,
                obj = item
            });

            ls.Add(new MenuPopupData()
            {
                label = "copy",
                onback = OnCopy,
                obj = item
            });
            MenuPopup.Instance.Show(evt.mousePosition, ls);
            // Debug.Log(evt.mousePosition);
        }
    }

    public string editorScene = "editorScene";

    private IEnumerator Start()
    {
        SceneManager.LoadScene(editorScene);
        yield return 0;
        var gos = SceneManager.GetSceneByName(editorScene).GetRootGameObjects();
        yield return 0;
        Ref(gos.ToList());
    }

    public void Create(File file)
    {
        if (file.t == "model")
        {
            ResExtendsMgr.LoadAsync<GameObject>(file.k, (obj =>
            {
                if (obj != null)
                {
                    var tf = GameObject.Instantiate(obj.transform);

                    AddItem(tf);
                }
            }));
        }
    }

    void RefChild(ref List<TreeViewItemData<HierarchyData>> parentList, Transform tf, ref int index)
    {
        int count = tf.childCount;


        var itemlist = new List<TreeViewItemData<HierarchyData>>(count);
        index += 1;
        var data = new HierarchyData();
        data.id = this.index;
        data.tf = tf;
        var floderItem = new TreeViewItemData<HierarchyData>(index, data, itemlist);
        parentList.Add(floderItem);

        for (var i = 0; i < count; i++)
        {
            var child = tf.GetChild(i);
            RefChild(ref itemlist, child, ref index);
        }
    }

    public static GameObject selectGameObject;
    int index = -1;
    public List<TreeViewItemData<HierarchyData>> items = new List<TreeViewItemData<HierarchyData>>();

    public void Ref(List<GameObject> gos)
    {
        // treeView.selectedIndex = -1;
        treeView.Clear();
        items.Clear();
        items = new List<TreeViewItemData<HierarchyData>>(gos.Count);


        for (int i = 0; i < gos.Count; i++)
        {
            RefChild(ref items, gos[i].transform, ref index);
        }

        Func<VisualElement> makeItem = () => new Label();

        Action<VisualElement, int> bindItem = (e, i) =>
        {
            var item = treeView.GetItemDataForIndex<HierarchyData>(i);
            item.index = i;
            (e as Label).text = item.tf.name;
        };
        treeView.SetRootItems(items);
        treeView.makeItem = makeItem;
        treeView.bindItem = bindItem;
        treeView.selectionType = SelectionType.Multiple;
        treeView.Rebuild();
    }

    void AddItem(Transform tf)
    {
        var newData = new HierarchyData();
        index = items.Count;
        newData.id = index;
        newData.index = index;
        newData.tf = tf;
        var item1 = new TreeViewItemData<HierarchyData>(index, newData);
        items.Add(item1);
        treeView.AddItem(item1);
        treeView.Rebuild();
    }

    void OnDel(MenuPopupData data)
    {
        var item = data.obj as HierarchyData;
        Debug.Log($"del:{item.id},{item.index},{item.tf},{items.Count}");
        treeView.RemoveAt(item.id);
        items.RemoveAt(item.index);
        treeView.SetRootItems(items);
        treeView.Rebuild();
        Destroy(item.tf.gameObject);
    }

    void OnCopy(MenuPopupData data)
    {
        var item = data.obj as HierarchyData;
        AddItem(Instantiate(item.tf));
    }
}